/**
 * 开闭原则需求</del>
  1. <del>实现小说书籍购买</del>
  2. <del>实现小说书籍打折促销（促销活动暂定为大于40打8折）</del>
  3. <del>实现小说数据打折多种促销（eg: 如果大于60，减12元）</del>
  4. <del>实现科技类数据支持多种促销方式 </del>
 */
// 书籍类
interface IBook {
  getName: { (): string; }
  getAuther: { (): string; }
  getPrice: { (): number; }
}

interface IOffBook extends IBook {
  getOffPrice: { (): number; }
}

// 定义打折方式
interface IOffTYpye {
  caculate: { (_price: number): number }
}


/**
 * 满60减10块
 */
class OffFullReduce implements IOffTYpye {
  caculate(_price: number) {
    if (isNaN(_price)) throw new Error('类型错误')
    if (_price <= 60) throw new Error('必须是大于60才能使用该优惠')
    return _price - 10;
  }
}


/**
 * 满90打8折
 */
class OffFullZhe implements IOffTYpye {
  caculate(_price: number) {
    if (isNaN(_price)) throw new Error('类型错误')
    if (_price <= 90) throw new Error('必须是大于90才能使用该优惠')
    return parseFloat((_price * 0.8).toFixed(2));
  }
}

// 小说书籍类
class NovelBook implements IBook {
  private name: string = ''
  private auther: string = ''
  private price: number = 0

  constructor(name: string, auther: string, price: number) {
    this.name = name;
    this.auther = auther;
    this.price = price;
  }

  getName() {
    return this.name;
  }
  getAuther() {
    return this.auther;
  }
  getPrice() {
    return this.price
  }
}

// 打折书籍
class OffNovelBook implements IOffBook {
  private name: string = ''
  private auther: string = ''
  private price: number = 0

  constructor(name: string, auther: string, price: number) {
    this.name = name;
    this.auther = auther;
    this.price = price;
  }
  // 打折价格
  getOffPrice() {
    // return this.price
    let _offPrice = this.price

    const offFullReduce = new OffFullReduce();
    const offFullZhe = new OffFullZhe()
    if (_offPrice > 90) return offFullZhe.caculate(_offPrice)
    if (_offPrice > 60) return offFullReduce.caculate(_offPrice)
    return _offPrice
  };

  getName() {
    return this.name;
  }
  getAuther() {
    return this.auther;
  }
  getPrice() {
    return this.price
  }
}

class OffScientBook implements IOffBook {
  private name: string = ''
  private auther: string = ''
  private price: number = 0

  constructor(name: string, auther: string, price: number) {
    this.name = name;
    this.auther = auther;
    this.price = price;
  }
  // 打折价格
  getOffPrice() {
    // return this.price
    let _offPrice = this.price

    const offFullReduce = new OffFullReduce();
    const offFullZhe = new OffFullZhe()
    if (_offPrice > 90) return offFullZhe.caculate(_offPrice)
    if (_offPrice > 60) return offFullReduce.caculate(_offPrice)
    return _offPrice
  };

  getName() {
    return this.name;
  }
  getAuther() {
    return this.auther;
  }
  getPrice() {
    return this.price
  }
}
class BookStore {
  private list: Set<IBook> = new Set()
  private offList: Set<IOffBook> = new Set()
  private offScientList: Set<IOffBook> = new Set()
  constructor() {
    // this.list.add(new NovelBook('西游记', '吴承恩', 89))
    // this.list.add(new NovelBook('三国演义', '施耐庵', 45))
    // this.list.add(new NovelBook('遥远的救世主', '六六', 60))

    this.offList.add(new OffNovelBook('西游记', '吴承恩', 89))
    this.offList.add(new OffNovelBook('三国演义', '施耐庵', 45))
    this.offList.add(new OffNovelBook('遥远的救世主', '六六', 67))


    this.offScientList.add(new OffNovelBook('人与自然', '王二二', 112))
    this.offScientList.add(new OffNovelBook('计算机科学与技术', '李三三', 333))
    this.offScientList.add(new OffNovelBook('算法设计与导论', '算六六', 90))
  }

  main() {
    // 已有逻辑，获取各个数据的价格
    this.list.forEach(v => {
      console.log(`${v.getName()}的作者是${v.getAuther()}, 他的原价价格是${v.getPrice()}`)
    })
    // 新逻辑，获取对应书籍对应的优惠后价格
    console.log('小说类:')
    this.offList.forEach(v => {
      console.log(`${v.getName()}的作者是${v.getAuther()}, 原价是${v.getPrice()}, 最终售卖价格是${v.getOffPrice()}`)
    })
    console.log('')

    console.log('科技类:')
    this.offScientList.forEach(v => {
      console.log(`${v.getName()}的作者是${v.getAuther()}, 原价是${v.getPrice()}, 最终售卖价格是${v.getOffPrice()}`)
    })
    console.log('')
  }
}

const bookStore = new BookStore();
bookStore.main()